azurerm_nat_gateway/azurerm_public_ip/azurerm_public_ip_prefix - support for new SKU StandardV2#31197
Conversation
…ort for new SKU StandardV2
|
Thanks @neil-yechenwei , LGTM! |
|
FYI it looks like #30957 is working on the same thing. |
gerrytan
left a comment
There was a problem hiding this comment.
Thank you @neil-yechenwei , I left some comments to address.
Also can you please rerun the acctest, I saw there were typos into the test prefix so some tests are not picked up.
| location = azurerm_resource_group.test.location | ||
| resource_group_name = azurerm_resource_group.test.name | ||
| sku_name = "StandardV2" | ||
| zones = ["1", "2", "3"] |
There was a problem hiding this comment.
Is specifying all zones required for StandardV2? If so please add a CustomizeDiff validator for this.
Refer to:
StandardV2 NAT Gateway is zone-redundant, meaning that it provides outbound connectivity from all zones in a region instead of a single zone like Standard NAT Gateway.
https://learn.microsoft.com/en-us/azure/nat-gateway/nat-overview
There was a problem hiding this comment.
Reason1: I think we should not use a CustomizeDiff validator to force users to specify zones, because the API also allows it when users do not specify them.
Reason2: About ignoring zones, according to the previous recommendations provided by HC, when the configuration of property A affects other properties—for example, property B—the affected property B should be handled by the user in the Terraform configuration. This allows users to clearly understand that when property A is modified, property B will also be impacted, rather than suppressing the issue through changes in the provider, which could cause property B to change without the user being aware of it. This can prevent users from encountering unexpected behavior. So, I add the comment for it.
|
@gerrytan , thanks for the comments. Please take another look. |
gerrytan
left a comment
There was a problem hiding this comment.
Thank you @neil-yechenwei , we still need to implement a CustomizeDiff validator to avoid user from seeing unexpected plan diff.
My understanding is if NAT gateway SKU is StandardV2, and zones are not set, the backend will set it to [1,2,3] right?
| * `sku_name` - (Optional) The SKU which should be used. At this time the only supported value is `Standard`. Defaults to `Standard`. | ||
| * `sku_name` - (Optional) The SKU which should be used. Possible values are `Standard` and `StandardV2`. Defaults to `Standard`. | ||
|
|
||
| -> **Note:** When `StandardV2` is enabled, service API will also enable `zones`. The user has to explicitly set this property in the Terraform configuration or handle it using `ignore_changes`. |
There was a problem hiding this comment.
Please implement a CustomizeDiff validation to force user to set zones to [1, 2 ,3] if StandardV2 SKU is used. A documentation note like this is not enough as user can miss it.
Also please reword this sentence to: 'StandardV2' SKU require zones to be set to [1,2,3], see [MS learn documentation](link to relevant doc) for more info
There was a problem hiding this comment.
I added CustomizeDiff validation and updated the md file. Thanks.
|
Also please rerun acctest against latest commit hash, with typos on the test prefix variable fixed. |
|
@gerrytan , thanks for the comments. I updated PR. Please take another look. I also rerun acctest.
|
gerrytan
left a comment
There was a problem hiding this comment.
Thank you @neil-yechenwei , I left 2 minor touch up comments to address and this should be good to go.
As discussed privately over DM, asking using to use ignore_changes will result in poor user experience / confusion. Although we can use optional + computed, but historically it is more prone to bugs, so thank you for implementing the CustomizeDiff validation instead.
| sort.Strings(zones) | ||
|
|
||
| requiredZones := []string{"1", "2", "3"} | ||
| if len(zones) != 3 || zones[0] != "1" || zones[1] != "2" || zones[2] != "3" { |
There was a problem hiding this comment.
Can be simplified using slices.Equal(zones, []string{"1", "2", "3"})
|
@teowa, I was looking at the PR I noticed there are two association resources that only append IDs to the NAT gateway model and never verify SKU compatibility. Microsoft’s NAT Gateway docs state that |
| * `reverse_fqdn` - (Optional) A fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN. | ||
|
|
||
| * `sku` - (Optional) The SKU of the Public IP. Accepted values are `Basic` and `Standard`. Defaults to `Standard`. Changing this forces a new resource to be created. | ||
| * `sku` - (Optional) The SKU of the Public IP. Possible values are `Basic`, `Standard`, and `StandardV2`. Defaults to `Standard`. Changing this forces a new Public IP to be created. |
There was a problem hiding this comment.
We should update this to use the standard wording per the contributor guidelines.
| * `sku` - (Optional) The SKU of the Public IP. Possible values are `Basic`, `Standard`, and `StandardV2`. Defaults to `Standard`. Changing this forces a new Public IP to be created. | |
| * `sku` - (Optional) The SKU of the Public IP. Possible values are `Basic`, `Standard`, and `StandardV2`. Defaults to `Standard`. Changing this forces a new resource to be created. |
| * `sku_tier` - (Optional) The SKU Tier that should be used for the Public IP. Possible values are `Regional` and `Global`. Defaults to `Regional`. Changing this forces a new resource to be created. | ||
|
|
||
| -> **Note:** When `sku_tier` is set to `Global`, `sku` must be set to `Standard`. | ||
| -> **Note:** When `sku_tier` is set to `Global`, `sku` must be set to `Standard` or `StandardV2`. |
There was a problem hiding this comment.
Is this correct? I thought the documentation said this had to be Standard.
There was a problem hiding this comment.
By tests, StandardV2 can also set with Global sku_tier. Actually it should be
-> Note: When sku_tier is set to Global, sku cannot be Basic
There was a problem hiding this comment.
Hi @teowa this is a good catch. We don't actually support Global tier on V2 IPs. We will add a validation from our side to block this. Only Standard SKU IPs support Global tier.
|
Hi @WodansSon , thanks for reviewing this! I've updated the code, please take another look! |
sreallymatt
left a comment
There was a problem hiding this comment.
Hi @neil-yechenwei / @teowa - I've left some comments inline.
Additionally, would you be able to get clarification from the service team regarding the actual retirement date? Currently all of our tests provisioning Basic public IP resources are passing.
| "1", | ||
| "2", | ||
| "3", | ||
| }, false), |
There was a problem hiding this comment.
I don't think we should start limiting input to zone/zones arguments. There is at least one region that supports 4 (eastus2euap, while a bit of a special case, users could be using it)
There was a problem hiding this comment.
Updated; now we just check that it isn't an empty string.
There was a problem hiding this comment.
from PG here - new creates of Basic SKU public IP resources as of March 2025 deprecation date is not supported. We are working on blocking in NRP, just hasn't rolled out yet.
| pluginsdk.CustomizeDiffShim(func(_ context.Context, d *pluginsdk.ResourceDiff, _ interface{}) error { | ||
| if !isPublicIPBasicSkuDeprecatedForCreation() { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
I'm a little confused as to why this function is here, isPublicIPBasicSkuDeprecatedForCreation() is already true so there's no need for it?
| } | ||
| } | ||
|
|
||
| const publicIPBasicSkuCreateDeprecationMessage = "creation of new `Basic` SKU public IP addresses is no longer permitted following its deprecation on March 31, 2025. This also affects `allocation_method` set to `Dynamic`, as it is only available with the `Basic` SKU. Existing `Basic` SKU public IP addresses can continue to be used until September 30, 2025. For more information, see https://azure.microsoft.com/updates/upgrade-to-standard-sku-public-ip-addresses-in-azure-by-30-september-2025-basic-sku-will-be-retired/" |
There was a problem hiding this comment.
I don't think this part is relevant given this date has passed
Existing Basic SKU public IP addresses can continue to be used until September 30, 2025.
| const publicIPBasicSkuCreateDeprecationMessage = "creation of new `Basic` SKU public IP addresses is no longer permitted following its deprecation on March 31, 2025. This also affects `allocation_method` set to `Dynamic`, as it is only available with the `Basic` SKU. Existing `Basic` SKU public IP addresses can continue to be used until September 30, 2025. For more information, see https://azure.microsoft.com/updates/upgrade-to-standard-sku-public-ip-addresses-in-azure-by-30-september-2025-basic-sku-will-be-retired/" | |
| const publicIPBasicSkuCreateDeprecationMessage = "creation of new `Basic` SKU public IP addresses is no longer permitted following its deprecation on March 31, 2025. This also affects `allocation_method` set to `Dynamic`, as it is only available with the `Basic` SKU. For more information, see https://azure.microsoft.com/updates/upgrade-to-standard-sku-public-ip-addresses-in-azure-by-30-september-2025-basic-sku-will-be-retired/" |
There was a problem hiding this comment.
I believe this also applies to StandardV2 so this check needs updating
There was a problem hiding this comment.
updated, allocation_method must be set to Static when sku is set to Standard or StandardV2
| losAngelesLocation = time.UTC | ||
| } | ||
|
|
||
| deprecationTime := time.Date(2025, time.April, 1, 0, 0, 0, 0, losAngelesLocation) |
There was a problem hiding this comment.
This date is in the past, so all the tests using this function are already irrelevant? (though they are still passing now)
There was a problem hiding this comment.
Despite being past the deprecation date, it is still possible to allocate a Basic SKU public IP.
There was a problem hiding this comment.
Yes, all tests that use sku=Basic for azurerm_public_ip will need to be migrated. These are being addressed in PR #31885.
There was a problem hiding this comment.
Despite being past the deprecation date, it is still possible to allocate a Basic SKU public IP.
new creates of Basic SKU public IP resources as of March 2025 deprecation date is not supported. Azure service team is working on blocking in NRP, just hasn't rolled out yet.
There was a problem hiding this comment.
Since the tests aren't failing yet and the function will always return true, can you remove this in favour of the migration in #31885?
There was a problem hiding this comment.
updated, this is removed now
| -> **Note:** Only one Availability Zone can be defined. For more information, please check out the [Azure documentation](https://learn.microsoft.com/en-us/azure/nat-gateway/nat-overview#availability-zones) | ||
| -> **Note:** For `Standard`, `zones` may be omitted for a no-zone deployment or set to a single Availability Zone. For more information, please see the [Azure documentation](https://learn.microsoft.com/azure/nat-gateway/nat-overview#availability-zones). | ||
|
|
||
| ~> **Note:** For `StandardV2`, `zones` should usually be omitted. `StandardV2` NAT Gateway is zone-redundant by default, and Azure may return `zones` as `1`, `2`, and `3` in state even when `zones` is not specified, see [MS learn documentation](https://learn.microsoft.com/azure/nat-gateway/nat-overview#standardv2-nat-gateway) for more info. |
There was a problem hiding this comment.
minor rephrasing that may make it more clear, WDYT?
| ~> **Note:** For `StandardV2`, `zones` should usually be omitted. `StandardV2` NAT Gateway is zone-redundant by default, and Azure may return `zones` as `1`, `2`, and `3` in state even when `zones` is not specified, see [MS learn documentation](https://learn.microsoft.com/azure/nat-gateway/nat-overview#standardv2-nat-gateway) for more info. | |
| ~> **Note:** For `StandardV2`, it is recommend to omit `zones`. The `StandardV2` NAT Gateway is zone-redundant by default, and Azure returns all available `zones` which may differ from the zones specified in config, see [MS learn documentation](https://learn.microsoft.com/azure/nat-gateway/nat-overview#standardv2-nat-gateway) for more info. |
|
|
||
| -> **Note:** Public IP Standard SKUs require `allocation_method` to be set to `Static`. | ||
|
|
||
| !> **Note:** **On 30 September 2025, `Basic` SKU public IP addresses will be retired in Azure.** You can continue to use your existing `Basic` SKU public IP addresses until then, however, you will no longer be able to create new ones after 31 March 2025. Please see the Azure Update [retirement notification](https://azure.microsoft.com/updates/upgrade-to-standard-sku-public-ip-addresses-in-azure-by-30-september-2025-basic-sku-will-be-retired/) for more information. |
There was a problem hiding this comment.
Date already passed? This would probably make more sense as something like `sku` can no longer be set to `Basic` as of <date> for new resources"
| * `sku_tier` - (Optional) The SKU Tier that should be used for the Public IP. Possible values are `Regional` and `Global`. Defaults to `Regional`. Changing this forces a new resource to be created. | ||
|
|
||
| -> **Note:** When `sku_tier` is set to `Global`, `sku` must be set to `Standard`. | ||
| -> **Note:** When `sku_tier` is set to `Global`, `sku` cannot be `Basic`. |
There was a problem hiding this comment.
Should this be validated for?
There was a problem hiding this comment.
updated, When sku_tier is set to Global, sku must be set to Standard.
|
Hi @sreallymatt , thanks for reviewing this, I've updated the code, please kindly take another look. |
|
This will be very much appreciated now that microsoft is deprecating default outbound access on VMs |
| Type: schema.TypeSet, | ||
| Optional: true, | ||
| // NOTE: O+C Azure may return availability zones from the API when not specified by the user | ||
| Computed: true, |
There was a problem hiding this comment.
Making this O+C breaks the existing behaviour of replacing the resource when a user removes zones from their deployment (when sku is Standard). We should try to keep this behaviour intact and we could use a DiffSuppressFunc instead.
Additionally, O+C doesn't entirely resolve the zones diff, currently a user could specify zones for StandardV2 in config (e.g. zones = ["1"]) which would lead to a perpetual diff, we should prevent users from setting zones on StandardV2 with a CustomizeDiff
e.g.
DiffSuppress:
DiffSuppressOnRefresh: true,
DiffSuppressFunc: func(_, _, _ string, d *schema.ResourceData) bool {
// when `sku_name` is `StandardV2`, Azure automatically spreads the deployment across all zones in the region
return d.Get("sku_name").(string) == string(natgateways.NatGatewaySkuNameStandardVTwo)
},
CustomizeDiff:
CustomizeDiff: func(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error {
if diff.Get("sku_name").(string) == string(natgateways.NatGatewaySkuNameStandardVTwo) {
if !diff.GetRawConfig().AsValueMap()["zones"].IsNull() {
return fmt.Errorf("%s resources with `sku_name` set to `%s` are zone-redundant by default, Azure automatically deploys across all available zones. The `zones` argument must be omitted", natGatewayResourceName, natgateways.NatGatewaySkuNameStandardVTwo)
}
}
return nil
},
| losAngelesLocation = time.UTC | ||
| } | ||
|
|
||
| deprecationTime := time.Date(2025, time.April, 1, 0, 0, 0, 0, losAngelesLocation) |
There was a problem hiding this comment.
Since the tests aren't failing yet and the function will always return true, can you remove this in favour of the migration in #31885?
|
Hi @sreallymatt , I've updated the code, please take another look. Thanks. |
sreallymatt
left a comment
There was a problem hiding this comment.
Thanks @teowa - LGTM ✅


Community Note
Description
This PR is to support for new SKU "StandardV2".
PR Checklist
For example: “
resource_name_here- description of change e.g. adding propertynew_property_name_here”Changes to existing Resource / Data Source
Testing
Change Log
Below please provide what should go into the changelog (if anything) conforming to the Changelog Format documented here.
azurerm_nat_gateway/azurerm_public_ip/azurerm_public_ip_prefix- support for new SKUStandardV2This is a (please select all that apply):
Related Issue(s)
Fixes # 0000
AI Assistance Disclosure
Rollback Plan
If a change needs to be reverted, we will publish an updated version of the provider.
Changes to Security Controls
Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.
Note
If this PR changes meaningfully during the course of review please update the title and description as required.